﻿using Microsoft.AspNetCore.Http;
using Leo.Core.Abp.Client.Contracts;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;

namespace Leo.Core.Abp.Client
{
    public class TokenRequestMessageHandler : DelegatingHandler, ITransientDependency
    {
        protected readonly IHttpContextAccessor _httpContextAccessor;
        public TokenRequestMessageHandler(IHttpContextAccessor httpContextAccessor)
        {
            this.InnerHandler = new HttpClientHandler();
            _httpContextAccessor = httpContextAccessor;
        }
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var token = Token;

            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);

            return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
        }

        protected virtual string GetTokenFromHttpHeader()
        {
            if (_httpContextAccessor.HttpContext?.Request?.Headers == null)
                return string.Empty;

            return _httpContextAccessor.HttpContext.Request.Headers.TryGetValue(JwtConsts.AuthorizationHeader, out var jwt)
                ? jwt.FirstOrDefault().Replace(JwtConsts.JwtHeaderPrefix, string.Empty) : string.Empty;
        }

        protected virtual string GetTokenFromCookie()
        {
            if (_httpContextAccessor.HttpContext?.Request?.Cookies == null)
                return string.Empty;

            return _httpContextAccessor.HttpContext.Request.Cookies.TryGetValue(JwtConsts.CookieName, out var token)
                ? token : string.Empty;
        }

        public virtual string Token
        {
            get
            {
                var token = GetTokenFromHttpHeader();
                return !string.IsNullOrEmpty(token) ? token : GetTokenFromCookie();
            }
        }
    }
}
